package com.jy.appmarket.download;

import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.text.TextUtils;
import android.util.Log;

import com.jy.appmarket.utils.LogUtil;
import com.jy.appmarket.utils.PackageUtils;
import com.jy.appmarket.utils.StorageConfig;

/**
 * 类说明：
 * 
 * @author Baker.li
 * @date 2014年5月19日
 * @version 1.0
 */

public class DownloadUtils {
	private static final String TAG = DownloadUtils.class.getSimpleName();
	public static final String DOWNLOAD_DIR = StorageConfig.DOWNLOAD_DIR;

	public static final boolean removeDownloadTmpFile(String dlId) {
		if (TextUtils.isEmpty(dlId)) {
			return false;
		}
		String path = DOWNLOAD_DIR + File.separator + dlId + ".apk.dl";
		return new File(path).delete();
	}

	public static final boolean removeDownloadedFile(String dlId) {
		if (TextUtils.isEmpty(dlId)) {
			return false;
		}
		String path = DownloadUtils.getDownloadApkFilePathById(dlId);
		return new File(path).delete();
	}

	public static final String generateDownloadId(String packageName, Integer versionCode) {
		if (TextUtils.isEmpty(packageName) || versionCode == null) {
			throw new IllegalArgumentException("generateDownloadId:packageName is empty");
		}
		// LogUtil.d(TAG, packageName + ":" + versionCode);
		return String.valueOf((packageName + ":" + versionCode).hashCode());
	}

	public static final String getDownloadApkFilePathById(String dlId) {
		if (TextUtils.isEmpty(dlId)) {
			throw new IllegalArgumentException("getDownloadFilePath:dlId is empty");
		}
		return DOWNLOAD_DIR + File.separator + dlId + ".apk";
	}

	public static final String getDownloadApkTmpFilePathById(String dlId) {
		if (TextUtils.isEmpty(dlId)) {
			throw new IllegalArgumentException("getDownloadFilePath:dlId is empty");
		}
		return DOWNLOAD_DIR + File.separator + dlId + ".apk.dl";
	}

	// public static final String getDownloadApkTmpFilePath(String url) {
	// if (TextUtils.isEmpty(url)) {
	// throw new IllegalArgumentException("getDownloadFilePath:url is empty");
	// }
	// return DOWNLOAD_DIR + File.separator + url.hashCode() + ".apk.dl";
	// }

	public static long getDownloadedBytes(String id) {
		if (TextUtils.isEmpty(id)) {
			return 0;
		}

		File file = new File(DOWNLOAD_DIR + File.separator + id + ".apk.dl");
		return file.length();
	}

	public static void setCommonHttpHeader(HttpURLConnection con) {
		con.setRequestProperty("Accept", "*/*");
		con.setRequestProperty("Accept-Language", "zh-CN, zh");
		con.setRequestProperty("Charset", "UTF-8,ISO-8859-1,US-ASCII,ISO-10646-UCS-2;q=0.6");
		con.setRequestProperty("User-Agent",
				"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322;"
						+ " .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
		con.setRequestProperty("Connection", "Keep-Alive");
	}

	public static Map<String, String> getHttpResponseHeader(HttpURLConnection http) {
		Map<String, String> header = new LinkedHashMap<String, String>();
		for (int i = 0;; i++) {
			String mine = http.getHeaderField(i);
			if (mine == null)
				break;

			String str = http.getHeaderFieldKey(i);
			if (str != null) {
				header.put(str.toLowerCase(Locale.CHINA), mine);
			}
		}
		return header;
	}

	public static boolean isWifiConnected(Context context) {
		if (context == null) {
			Log.w(TAG, "context is null");
			return false;
		}
		ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (cm == null) {
			Log.w(TAG, "cm is null");
			return false;
		}

		NetworkInfo ni = null;
		try {
			ni = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		} catch (RuntimeException re) {
			// ignore it
		}
		if (ni == null) {
			Log.w(TAG, "wifi info is null");
			return false;
		}
		return NetworkInfo.State.CONNECTED == ni.getState();
	}

	public static boolean isNetworkAvailable(Context context) {
		if (context == null) {
			Log.w(TAG, "context is null");
			return false;
		}
		ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (cm == null) {
			Log.w(TAG, "cm is null");
			return false;
		}

		NetworkInfo ni = null;
		try {
			ni = cm.getActiveNetworkInfo();
		} catch (RuntimeException re) {
			// ignore it
		}
		if (ni == null) {
			Log.w(TAG, "getActiveNetworkInfo failed");
			return false;
		}
		return NetworkInfo.State.CONNECTED == ni.getState();
	}

	public static boolean isMobileNetwork(Context context) {
		if (context == null) {
			Log.w(TAG, "context is null");
			return false;
		}
		ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (cm == null) {
			Log.w(TAG, "cm is null");
			return false;
		}

		NetworkInfo ni = null;
		try {
			ni = cm.getActiveNetworkInfo();
		} catch (RuntimeException re) {
			// ignore it
		}
		if (ni == null) {
			Log.w(TAG, "getActiveNetworkInfo failed");
			return false;
		}
		return ni.getType() == ConnectivityManager.TYPE_MOBILE;
	}

	public static boolean isCmwap(Context context) {
		ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo netWrokInfo = manager.getActiveNetworkInfo();

		if (netWrokInfo == null) {
			return false;
		}

		String typeName = netWrokInfo.getTypeName();
		String extraInfo = netWrokInfo.getExtraInfo();

		return ("MOBILE".equalsIgnoreCase(typeName) && ("cmwap".equalsIgnoreCase(extraInfo)
				|| "3gwap".equalsIgnoreCase(extraInfo) || "uniwap".equalsIgnoreCase(extraInfo)));
	}

	public static HttpURLConnection getCmwapConnect(String requestUrl) throws IOException {
		URL url = new URL(requestUrl);
		HttpURLConnection con;

		LogUtil.i(TAG, "use cmwap...");

		String host = url.getHost();
		int port = url.getPort();
		if (port == -1) {
			requestUrl = requestUrl.replaceAll(host, "10.0.0.172:80");
		} else {
			requestUrl = requestUrl.replaceAll(host + ":" + port, "10.0.0.172:80");
		}

		url = new URL(requestUrl);
		con = (HttpURLConnection) url.openConnection();

		String xOnlineHost = null;
		if (port == -1) {
			xOnlineHost = host;
		} else {
			xOnlineHost = host + ":" + port;
		}
		con.setRequestProperty("Host", "10.0.0.172");
		con.setRequestProperty("X-Online-Host", xOnlineHost);
		return con;
	}

	public static boolean canInstall(Context context) {
		if (context == null) {
			Log.w(TAG, "canInstall context is null");
			return false;
		}

		ApplicationInfo ai = context.getApplicationInfo();
		if (ai == null) {
			Log.w(TAG, "canInstall ApplicationInfo is null");
			return false;
		}
		return (ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
	}

	public static boolean removeInstalledApk(Context context, String pkg, String md5) {
		DownloadDatabase db = DownloadDatabase.getInstance(context.getApplicationContext());
		Cursor cur = null;
		String dlId = null;
		try {
			cur = db.query(DownloadDatabase.COL_PKG_NAME + "=? AND " + DownloadDatabase.COL_MD5 + " =?",
					new String[] { pkg, md5 }, null);
			if (cur.moveToFirst()) {
				dlId = cur.getString(cur.getColumnIndex(DownloadDatabase.COL_DL_ID));
			}
			if (TextUtils.isEmpty(dlId)) {
				return false;
			}
			File file = new File(getDownloadApkFilePathById(dlId));
			if (!file.exists()) {
				return false;
			}
			return file.delete();
		} finally {
			if (cur != null) {
				cur.close();
			}
		}
	}

	public static DownloadItem getDownloadItem(Context context, String pkg, String md5) {
		if (context == null) {
			return null;
		}
		DownloadItem di = null;
		DownloadDatabase db = DownloadDatabase.getInstance(context.getApplicationContext());
		Cursor cur = null;
		try {
			cur = db.query(DownloadDatabase.COL_PKG_NAME + "=? AND " + DownloadDatabase.COL_MD5 + " =?",
					new String[] { pkg, md5 }, null);
			if (cur.moveToFirst()) {
				di = DownloadDatabase.buildFromCursor(cur);
			}
			return di;
		} finally {
			if (cur != null) {
				cur.close();
			}
		}
	}

	/**
	 * 指定的包名任务是否存在于数据库中
	 * 
	 * @param context
	 * @param pkgName
	 *            包名
	 * @return
	 */
	public static boolean downloadExist(Context context, String pkgName) {
		if (context == null) {
			return false;
		}
		DownloadDatabase db = DownloadDatabase.getInstance(context.getApplicationContext());
		Cursor cur = null;
		try {
			cur = db.query(DownloadDatabase.COL_PKG_NAME + "=?", new String[] { pkgName }, null);
			return cur.moveToFirst();
		} finally {
			if (cur != null) {
				cur.close();
			}
		}
	}

	public static int getUnfinishedTaskCount(Context context) {
		if (context == null) {
			return 0;
		}
		DownloadDatabase db = DownloadDatabase.getInstance(context.getApplicationContext());
		Cursor cur = null;
		try {
			cur = db.query(null, null, null);
			int count = 0;
			for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
				DownloadItem di = DownloadDatabase.buildFromCursor(cur);
				if (di != null) {
					Integer vc = PackageUtils.getVersionCode(context, di.getPkgName());

					if (vc == null || vc < di.getVersionCode()) {
						count++;
					}
				}
			}
			return count;
		} finally {
			if (cur != null) {
				cur.close();
			}
		}
	}

}
